﻿using KPIS.GERP.Models;
using KPIS.GERP.Models.Class;
using KPIS.GERP.Models.ICM;
using KPIS.GERP.Models.SYS;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Linq.Dynamic;
using System.ServiceModel;
using System.Web.Mvc;

namespace KPIS.GERP.WCF.GIMS
{
    [ServiceContract]
    public interface IIcmMasterService
    {
        #region MasPurchaseRegular
        [OperationContract]
        IEnumerable<MasPurchaseRegular> SelectPurchaseRegular(MasPurchaseRegular criteriaModel = null, List<string> includeSubObjectString = null);

        [OperationContract]
        int InsertPurchaseRegular(MasPurchaseRegular model, int createByUserId);

        [OperationContract]
        void UpdatePurchaseRegular(MasPurchaseRegular model, int updateByUserId);

        [OperationContract]
        void DeletePurchaseRegular(int id, int deleteByUserId);
        #endregion

        #region MasPurchaseRegularMapping
        [OperationContract]
        IEnumerable<MasPurchaseRegularMapping> SelectPurchaseRegularMapping(MasPurchaseRegularMapping criteriaModel = null, List<string> includeSubObjectString = null);

        [OperationContract]
        int InsertPurchaseRegularMapping(MasPurchaseRegularMapping model, int createByUserId);

        [OperationContract]
        void UpdatePurchaseRegularMapping(MasPurchaseRegularMapping model, int updateByUserId);

        [OperationContract]
        void DeletePurchaseRegularMapping(int id, int deleteByUserId);
        #endregion

        #region MasUnit

        [OperationContract]
        IEnumerable<MasUnit> SelectUnit(MasUnit criteriaModel = null, List<string> includeSubObjectString = null);
		
        [OperationContract]
        int InsertUnit(MasUnit model, int createByUserId);

        [OperationContract]
        void UpdateUnit(MasUnit model, int updateByUserId);

        [OperationContract]
        void DeleteUnit(int id, int deleteByUserId);

        #endregion

        #region MasPurchaseType

        [OperationContract]
        List<MasPurchaseType> SelectPurchaseType(MasPurchaseType criteriaModel = null, List<string> includeSubObjectString = null);

        [OperationContract]
        void UpdatePurchaseType(MasPurchaseType model, int updateByUserId);

        #endregion

        #region MasPurchaseMethod
        [OperationContract]
        IEnumerable<MasPurchaseMethod> SelectPurchaseMethod(MasPurchaseMethod criteriaModel = null, List<string> includeSubObjectString = null);

        [OperationContract]
        IList<SelectListItem> SelectListPurchaseMethod(MasPurchaseMethod criteriaModel = null, bool insertBlankAtFirst = true);

        [OperationContract]
        List<SelectListItem> SelectListMethod();

        [OperationContract]
        int InsertPurchaseMethod(MasPurchaseMethod model, int createByUserId);

        [OperationContract]
        void UpdatePurchaseMethod(MasPurchaseMethod model, int updateByUserId);

        [OperationContract]
        void DeletePurchaseMethod(int id, int deleteByUserId);
        #endregion

        [OperationContract]
        decimal? GetRequestAmount(int appPrcGrpId, int refId);

		#region Select List

	    [OperationContract]
	    List<SelectListItem> SelectListPurchaseType(MasPurchaseType criteriaModel = null, bool insertBlankAtFirst = true);

		[OperationContract]
		IList<SelectListItem> SelectListUnit(MasUnit criteriaModel = null, bool insertBlankAtFirst = true);
	    #endregion
    }

	[ServiceErrorBehavior(typeof(ElmahErrorHandler))]
    public class IcmMasterService : IIcmMasterService
    {
        #region MasPurchaseRegular

        public IEnumerable<MasPurchaseRegular> SelectPurchaseRegular(MasPurchaseRegular criteriaModel = null, List<string> includeSubObjectString = null)
        {
            try
            {
                using (var context = new GERPContext(false))
                {
                    IQueryable<MasPurchaseRegular> query = context.MasPurchaseRegulars;

                    if (includeSubObjectString != null)
                    {
                        query = includeSubObjectString.Aggregate(query, (current, includePath) => current.Include(includePath));
                    }

                    if (criteriaModel != null)
                    {
                        object[] param;
                        query = query.Where(KPIS.GERP.Models.Class.Utility.GenerateWhereString(criteriaModel, out param), param);
                    }

                    var x = query.ToList();
                    return x;
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        
        public int InsertPurchaseRegular(MasPurchaseRegular model, int createByUserId)
        {
            try
            {
                using (var context = new GERPContext())
                {
                    model.RecordStatus = RecordStatus.UsedStatus;
                    model.CreatedBy = createByUserId;
                    model.CreatedWhen = DateTime.Now;
                    context.MasPurchaseRegulars.Add(model);
                    context.SaveChanges();

                    return model.RegularId;
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public void UpdatePurchaseRegular(MasPurchaseRegular model, int updateByUserId)
        {
            try
            {
                using (var context = new GERPContext())
                {
                    context.Entry(model).State = EntityState.Modified;
                    model.UpdatedBy = updateByUserId;
                    model.UpdatedWhen = DateTime.Now;
                    context.SaveChanges();
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }            
        }

        public void DeletePurchaseRegular(int id, int deleteByUserId)
        {
            try
            {
                using (var context = new GERPContext())
                {
                    var modelToDelete = context.MasPurchaseRegulars.Find(id);
                    if (modelToDelete == null) return;

                    context.Entry(modelToDelete).State = EntityState.Modified;
                    modelToDelete.RecordStatus = RecordStatus.DeletedStatus;
                    modelToDelete.UpdatedBy = deleteByUserId;
                    modelToDelete.UpdatedWhen = DateTime.Now;
                    context.SaveChanges();
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        #endregion

        #region MasPurchaseRegularMapping
        public IEnumerable<MasPurchaseRegularMapping> SelectPurchaseRegularMapping(MasPurchaseRegularMapping criteriaModel = null, List<string> includeSubObjectString = null)
        {
            try
            {
                using (var context = new GERPContext(false))
                {
                    IQueryable<MasPurchaseRegularMapping> query = context.MasPurchaseRegularMappings;

                    if (includeSubObjectString != null)
                    {
                        query = includeSubObjectString.Aggregate(query, (current, includePath) => current.Include(includePath));
                    }

                    if (criteriaModel != null)
                    {
                        object[] param;
                        query = query.Where(KPIS.GERP.Models.Class.Utility.GenerateWhereString(criteriaModel, out param), param);
                    }

                    return query.ToList();
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public int InsertPurchaseRegularMapping(MasPurchaseRegularMapping model, int createByUserId)
        {
            try
            {
                using (var context = new GERPContext())
                {
                    var existData = context.MasPurchaseRegularMappings
                        .Where(m => m.BgSourceId == model.BgSourceId
                            && m.RegularId == model.RegularId
                            && m.RecordStatus != RecordStatus.DeletedStatus).ToList();

                    if (existData.Count == 0)
                    {
                        model.RecordStatus = RecordStatus.UsedStatus;
                        model.CreatedBy = createByUserId;
                        model.CreatedWhen = DateTime.Now;
                        context.MasPurchaseRegularMappings.Add(model);
                        context.SaveChanges();
                        return model.RegularMapId;
                    }
                    else
                    {
                        throw new Exception("เกิดข้อผิดพลาด!! ข้อมูลนี้มีบันทึกอยู่แล้ว");
                    }
                    
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public void UpdatePurchaseRegularMapping(MasPurchaseRegularMapping model, int updateByUserId)
        {
            try
            {
                using (var context = new GERPContext())
                {
                    var existData = context.MasPurchaseRegularMappings
                        .Where(m => m.BgSourceId == model.BgSourceId
                            && m.RegularId == model.RegularId
                            && m.RecordStatus != RecordStatus.DeletedStatus
                            && m.RegularMapId != model.RegularMapId).ToList();

                    if (existData.Count == 0)
                    {
                        context.Entry(model).State = EntityState.Modified;
                        model.UpdatedBy = updateByUserId;
                        model.UpdatedWhen = DateTime.Now;
                        context.SaveChanges();
                    }
                    else
                    {
                        throw new Exception("เกิดข้อผิดพลาด!! ข้อมูลนี้มีบันทึกอยู่แล้ว");
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public void DeletePurchaseRegularMapping(int id, int deleteByUserId)
        {
            try
            {
                using (var context = new GERPContext())
                {
                    var modelToDelete = context.MasPurchaseRegularMappings.Find(id);
                    if (modelToDelete == null) return;

                    context.Entry(modelToDelete).State = EntityState.Modified;
                    modelToDelete.RecordStatus = RecordStatus.DeletedStatus;
                    modelToDelete.UpdatedBy = deleteByUserId;
                    modelToDelete.UpdatedWhen = DateTime.Now;
                    context.SaveChanges();
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        #endregion

        #region MasUnit

        public IEnumerable<MasUnit> SelectUnit(MasUnit criteriaModel = null, List<string> includeSubObjectString = null)
        {
            try
            {
                using (var context = new GERPContext(false))
                {
                    IQueryable<MasUnit> query = context.MasUnits;

                    if (includeSubObjectString != null)
                    {
                        query = includeSubObjectString.Aggregate(query, (current, includePath) => current.Include(includePath));
                    }

                    if (criteriaModel != null)
                    {
                        object[] param;
                        query = query.Where(KPIS.GERP.Models.Class.Utility.GenerateWhereString(criteriaModel, out param), param);
                    }

                    var x = query.ToList();
                    return x;
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public IList<SelectListItem> SelectListUnit(MasUnit criteriaModel = null, bool insertBlankAtFirst = true)
        {
            var list = new List<SelectListItem>();

            try
            {
                using (var context = new GERPContext(false))
                {
                    IQueryable<MasUnit> query = context.MasUnits;

                    if (criteriaModel != null)
                    {
                        object[] param;
                        query = query.Where(KPIS.GERP.Models.Class.Utility.GenerateWhereString(criteriaModel, out param), param);
                    }

                    var x = query.ToList();
					if (insertBlankAtFirst) list.Add(new SelectListItem {Text = string.Empty, Value = string.Empty});
                    foreach (var MasUnit in x)
                    {
                        var item = new SelectListItem { Text = MasUnit.Name, Value = MasUnit.UnitId.ToString() };
                        list.Add(item);
                    }
                }

            }
            catch (Exception ex)
            {
                throw ex;
            }

            return list;
        }

        public int InsertUnit(MasUnit model, int createByUserId)
        {
            try
            {
                using (var context = new GERPContext())
                {
                    model.RecordStatus = RecordStatus.UsedStatus;
                    model.CreatedBy = createByUserId;
                    model.CreatedWhen = DateTime.Now;
                    context.MasUnits.Add(model);
                    context.SaveChanges();

                    return model.UnitId;
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public void UpdateUnit(MasUnit model, int updateByUserId)
        {
            try
            {
                using (var context = new GERPContext())
                {
                    context.Entry(model).State = EntityState.Modified;
                    model.UpdatedBy = updateByUserId;
                    model.UpdatedWhen = DateTime.Now;
                    context.SaveChanges();
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public void DeleteUnit(int id, int deleteByUserId)
        {
            try
            {
                using (var context = new GERPContext())
                {
                    var modelToDelete = context.MasUnits.Find(id);
                    if (modelToDelete == null) return;

                    context.Entry(modelToDelete).State = EntityState.Modified;
                    modelToDelete.RecordStatus = RecordStatus.DeletedStatus;
                    modelToDelete.UpdatedBy = deleteByUserId;
                    modelToDelete.UpdatedWhen = DateTime.Now;
                    context.SaveChanges();
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

	    public decimal? GetRequestAmount(int appPrcGrpId, int refId)
	    {
	        /*
            AppPrcGrpId	Code	Name	        AppPrcId	Name
            6	        PP	คำขออนุมัติแจ้งความประสงค์	6	คำขออนุมัติแจ้งความประสงค์
            7	            ขอเบิกวัสดุครุภัณฑ์	    7	ขอเบิกวัสดุครุภัณฑ์                <-- Request Parcel View
            8	        PR	ขออนุมัติขอซื้อขอจ้าง	    8	ขออนุมัติขอซื้อขอจ้างเกิน๑๐๐๐๐๐บาท
            8	        PR	ขออนุมัติขอซื้อขอจ้าง	    9	ขออนุมัติขอซื้อขอจ้างไม่เกิน๑๐๐๐๐๐บาท
            10	        PO-Purchase	ขออนุมัติใบสั่ง	10	ขออนุมัติใบสั่งเกิน๕๐๐๐๐๐บาท       
            10	        PO-Purchase	ขออนุมัติใบสั่ง	11	ขออนุมัติใบสั่งไม่เกิน๕๐๐๐๐๐บาท     
            12	        BD	ขออนุมัติประกาศ	        12	ขออนุมัติประกาศ
            13	        PO-Contract	ขออนุมัติงานสัญ	13	ขออนุมัติงานสัญญา               
            14	        DN	ขออนุมัติการตรวจรับ	    24	การตรวจรับไม่เกิน๕๐๐๐๐บาท 
            14	        DN	ขออนุมัติการตรวจรับ	    25	การตรวจรับเกิน๕๐๐๐๐บาท */
	        decimal? requestAmount = null;
	        using (var db = new GERPContext(false))
	        {
	            switch (appPrcGrpId)
	            {
	                case 6:
	                    requestAmount = db.PrePurchaseRequestItems.Where(o => o.PprId == refId).Sum(o => o.Amount);
	                    break;
	                case 7:
	                    requestAmount = db.RequestParcelDtls.Where(o => o.ReqId == refId).Sum(o => o.Quantity);
	                    break;
	                case 8:
	                    var prItems = db.PurchaseRequestItems.Where(o => o.PrId == refId);
	                    var itemIds = prItems.Select(o => o.PrItemId).ToArray();
	                    var quos = db.BidderQuotations.Where(o =>
	                        o.Selected == "1" &&
	                        o.PrItemId.HasValue &&
	                        itemIds.Contains(o.PrItemId.Value));

	                    requestAmount = quos.Sum(o => o.NetAmount);
	                    break;
	                case 10:
	                    requestAmount = db.PurchaseOrderItems
	                        .Where(o => o.PoId == refId).Sum(o => o.BidderQuotation.NetAmount);
	                    break;
	                case 13:
	                    requestAmount = db.PurchaseOrderItems
	                        .Where(o => o.PoId == refId).Sum(o => o.BidderQuotation.NetAmount);
	                    break;
	                case 12:
	                    var bid = db.Bids.FirstOrDefault(o => o.BidId == refId);
	                    if (bid != null)
	                    {
	                        requestAmount = db.PurchaseRequestItems.Where(o => o.PrId == bid.PrId).Sum(o => o.Amount);
	                    }
	                    break;
	                case 14:
	                    var dnItemsSumNetAmount = db.DeliveryNoteItems.Where(o => o.DnId == refId).Sum(o => o.NetAmount);
	                    requestAmount = dnItemsSumNetAmount.HasValue
	                        ? Convert.ToDecimal(dnItemsSumNetAmount.Value)
	                        : (decimal?) null;
	                    break;
	                default:
	                    break;
	            }
	        }
	        return requestAmount;
	    }

	    public List<SelectListItem> SelectListPurchaseType(MasPurchaseType criteriaModel = null, bool insertBlankAtFirst = true)
		{
			var list = new List<SelectListItem>(); 
			try
			{
				using (var context = new GERPContext(false))
				{
					IQueryable<MasPurchaseType> query = context.MasPurchaseTypes;

					if (criteriaModel != null)
					{
						object[] param;
						query = query.Where(KPIS.GERP.Models.Class.Utility.GenerateWhereString(criteriaModel, out param), param);
					}

					var x = query.ToList();
					if (insertBlankAtFirst) list.Add(new SelectListItem { Text = string.Empty, Value = string.Empty });
					foreach (var data in x)
					{
						var item = new SelectListItem { Text = data.PcTypeName, Value = data.PcTypeId.ToString() };
						list.Add(item);
					}
				}
			}
			catch (Exception ex)
			{
				KPIS.GERP.Models.Class.GerpLog.Error(ex.Message);
			}

			return list; 
		}

        
		#endregion

        #region MasPurchaseType

        public List<MasPurchaseType> SelectPurchaseType(MasPurchaseType criteriaModel = null, List<string> includeSubObjectString = null)
        {
            try
            {
                using (var context = new GERPContext(false))
                {
                    IQueryable<MasPurchaseType> query = context.MasPurchaseTypes;

                    if (includeSubObjectString != null)
                    {
                        query = includeSubObjectString.Aggregate(query, (current, includePath) => current.Include(includePath));
                    }

                    if (criteriaModel != null)
                    {
                        object[] param;
                        query = query.Where(KPIS.GERP.Models.Class.Utility.GenerateWhereString(criteriaModel, out param), param);
                    }

                    var Tmp = query.ToList();
                    return Tmp;
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }

        }

        public void UpdatePurchaseType(MasPurchaseType model, int updateByUserId)
        {
            try
            {
                using (var context = new GERPContext())
                {
                    context.Entry(model).State = EntityState.Modified;
                    model.UpdatedBy = updateByUserId;
                    model.UpdatedWhen = DateTime.Now;
                    context.SaveChanges();
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        #endregion

        #region MasPurchaseMethod

        public IEnumerable<MasPurchaseMethod> SelectPurchaseMethod(MasPurchaseMethod criteriaModel = null, List<string> includeSubObjectString = null)
        {
            try
            {
                using (var context = new GERPContext(false))
                {
                    IQueryable<MasPurchaseMethod> query = context.MasPurchaseMethods;

                    if (includeSubObjectString != null)
                    {
                        query = includeSubObjectString.Aggregate(query, (current, includePath) => current.Include(includePath));
                    }

                    if (criteriaModel != null)
                    {
                        object[] param;
                        query = query.Where(KPIS.GERP.Models.Class.Utility.GenerateWhereString(criteriaModel, out param), param);
                    }

                    var x = query.ToList();
                    return x;
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public IList<SelectListItem> SelectListPurchaseMethod(MasPurchaseMethod criteriaModel = null, bool insertBlankAtFirst = true)
        {
            var list = new List<SelectListItem>();

            try
            {
                using (var context = new GERPContext(false))
                {
                    IQueryable<MasPurchaseMethod> query = context.MasPurchaseMethods;

                    if (criteriaModel != null)
                    {
                        object[] param;
                        query = query.Where(KPIS.GERP.Models.Class.Utility.GenerateWhereString(criteriaModel, out param), param);
                    }

                    var x = query.ToList();
                    if (insertBlankAtFirst) list.Add(new SelectListItem { Text = "ไม่ระบุ", Value = string.Empty });
                    foreach (var MasPurchaseMethod in x)
                    {
                        var item = new SelectListItem { Text = MasPurchaseMethod.Name,
                            Value = MasPurchaseMethod.PcMethodId.ToString() };
                        list.Add(item);
                    }
                }

            }
            catch (Exception ex)
            {
                throw ex;
            }

            return list;
        }

        public List<SelectListItem> SelectListMethod()
        {
            GERPContext db = new GERPContext();
            var list = new List<SelectListItem>();
            list.Add(new SelectListItem { Selected = true, Text = "....เลือกรายการ....", Value = "" });

            try
            {
                List<Models.ICM.MasPurchaseType> listMethod = (from m in db.MasPurchaseTypes
                                                     where m.RecordStatus != Models.SYS.RecordStatus.DeletedStatus
                                                     select m).ToList();

                foreach (var PurchaseTypes in listMethod)
                {
                    var item = new SelectListItem { Text = PurchaseTypes.PcTypeName, Value = PurchaseTypes.PcTypeId.ToString() };
                    list.Add(item);
                }

            }
            catch (Exception ex)
            {
                throw ex;
            }

            return list;
        }

        public int InsertPurchaseMethod(MasPurchaseMethod model, int createByUserId)
        {
            try
            {
                using (var context = new GERPContext())
                {
                    model.RecordStatus = RecordStatus.UsedStatus;
                    model.CreatedBy = createByUserId;
                    model.CreatedWhen = DateTime.Now;
                    context.MasPurchaseMethods.Add(model);
                    context.SaveChanges();

                    return model.PcMethodId;
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public void UpdatePurchaseMethod(MasPurchaseMethod model, int updateByUserId)
        {
            try
            {
                using (var context = new GERPContext())
                {
                    context.Entry(model).State = EntityState.Modified;
                    model.UpdatedBy = updateByUserId;
                    model.UpdatedWhen = DateTime.Now;
                    context.SaveChanges();
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public void DeletePurchaseMethod(int id, int deleteByUserId)
        {
            try
            {
                using (var context = new GERPContext())
                {
                    var modelToDelete = context.MasPurchaseMethods.Find(id);
                    if (modelToDelete == null) return;

                    context.Entry(modelToDelete).State = EntityState.Modified;
                    modelToDelete.RecordStatus = RecordStatus.DeletedStatus;
                    modelToDelete.UpdatedBy = deleteByUserId;
                    modelToDelete.UpdatedWhen = DateTime.Now;
                    context.SaveChanges();
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        #endregion
    }
}
